//========================================================================================
//  
//  $File: $
//  
//  Owner: Toan Nguyen
//  
//  $Author: $
//  
//  $DateTime: $
//  
//  $Revision: $
//  
//  $Change: $
//  
//  Copyright 1997-2008 Adobe Systems Incorporated. All rights reserved.
//  
//  NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance 
//  with the terms of the Adobe license agreement accompanying it.  If you have received
//  this file from a source other than Adobe, then your use, modification, or 
//  distribution of it requires the prior written permission of Adobe.
//  
//========================================================================================

#include "VCPlugInHeaders.h"

// Interface includes:
#include "IPanelControlData.h"
#include "ISubject.h"

// General includes:
#include "CDialogObserver.h"
#include "AMPCAlert.h"
#include "IWidgetParent.h"
#include "IApplication.h"
#include "IDialogMgr.h"
#include "CoreResTypes.h"
#include "LocaleSetting.h"
#include "RsrcSpec.h"

// Project includes:
#include "AMPID.h"
#include "CDialogController.h"
#include "HTTPRequestHelper.h"
#include "JSONHelper.h"
#include "AMPLogDataRecord.h"
#include "AMGlobal.h"
#include "SDKFileHelper.h"
#include "SDKLayoutHelper.h"
#include "FileUtils.h"
class DlgCMSLoginDialogObserver : public CDialogObserver
{
	public:
		/**
			Constructor.
			@param boss interface ptr from boss object on which this interface is aggregated.
		*/
		DlgCMSLoginDialogObserver(IPMUnknown* boss) : CDialogObserver(boss) {}

		/** Destructor. */
		virtual ~DlgCMSLoginDialogObserver() {}

		/** 
			Called by the application to allow the observer to attach to the subjects 
			to be observed, in this case the dialog's info button widget. If you want 
			to observe other widgets on the dialog you could add them here. 
		*/
		virtual void AutoAttach();

		/** Called by the application to allow the observer to detach from the subjects being observed. */
		virtual void AutoDetach();

		/**
			Called by the host when the observed object changes, in this case when
			the dialog's info button is clicked.
			@param theChange specifies the class ID of the change to the subject. Frequently this is a command ID.
			@param theSubject points to the ISubject interface for the subject that has changed.
			@param protocol specifies the ID of the changed interface on the subject boss.
			@param changedBy points to additional data about the change. 
				Often this pointer indicates the class ID of the command that has caused the change.
		*/
		virtual void Update
		(
			const ClassID& theChange, 
			ISubject* theSubject, 
			const PMIID& protocol, 
			void* changedBy
		);
private:
	void DoCloseDialog(int32 nTypeDialog);
	
	IDialog* DoOpenDialog(int32 nTypeDialog);
};


/* CREATE_PMINTERFACE
 Binds the C++ implementation class onto its 
 ImplementationID making the C++ code callable by the 
 application.
*/
CREATE_PMINTERFACE(DlgCMSLoginDialogObserver, kDlgCMSLoginDialogObserverImpl)

/* AutoAttach
*/
void DlgCMSLoginDialogObserver::AutoAttach()
{
	// Call the base class AutoAttach() function so that default behavior
	// will still occur (OK and Cancel buttons, etc.).
	CDialogObserver::AutoAttach();

	do
	{
		// Get the IPanelControlData interface for the dialog:
		InterfacePtr<IPanelControlData> panelControlData(this, UseDefaultIID());
		if (panelControlData == nil)
		{
			ASSERT_FAIL("DlgCMSLoginDialogObserver::AutoAttach() panelControlData invalid");
			break;
		}
		
		// Now attach to BasicDialog's info button widget.
		AttachToWidget(kBscDlgIconSuiteWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);							//<--20120420

		// Attach to other widgets you want to handle dynamically here.
		AttachToWidget(kBscDlgLoginButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData);	// login CMS server		//<--20120420
		
		AttachToWidget(kAMPRadioAutoWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);
		
		AttachToWidget(kAMPRadioManualWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);
		
		AttachToWidget(kAMPButtonAdvanceWidgetId, IID_IBOOLEANCONTROLDATA, panelControlData);

	} while (false);
}

/* AutoDetach
*/
void DlgCMSLoginDialogObserver::AutoDetach()
{
	// Call base class AutoDetach() so that default behavior will occur (OK and Cancel buttons, etc.).
	CDialogObserver::AutoDetach();

	do
	{
		// Get the IPanelControlData interface for the dialog:
		InterfacePtr<IPanelControlData> panelControlData(this, UseDefaultIID());
		if (panelControlData == nil)
		{
			ASSERT_FAIL("DlgCMSLoginDialogObserver::AutoDetach() panelControlData invalid");
			break;
		}
		
		// Now we detach from BasicDialog's info button widget.
		DetachFromWidget(kBscDlgIconSuiteWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);								//<--20120420

		// Detach from other widgets you handle dynamically here.
		DetachFromWidget(kBscDlgLoginButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData);	// login CMS server		//<--20120420
		
		DetachFromWidget(kAMPRadioAutoWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);
		
		DetachFromWidget(kAMPRadioManualWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);
		
		DetachFromWidget(kAMPButtonAdvanceWidgetId, IID_IBOOLEANCONTROLDATA, panelControlData);
	} while (false);
}

/* Update
*/
void DlgCMSLoginDialogObserver::Update
(
	const ClassID& theChange, 
	ISubject* theSubject, 
	const PMIID &protocol, 
	void* changedBy
)
{
	// Call the base class Update function so that default behavior will still occur (OK and Cancel buttons, etc.).
	CDialogObserver::Update(theChange, theSubject, protocol, changedBy);

	do
	{
		InterfacePtr<IControlView> controlView(theSubject, UseDefaultIID());
		if (controlView == nil)
		{
			ASSERT_FAIL("DlgCMSLoginDialogObserver::Update() controlView invalid");
			break;
		}

		// Get the button ID from the view.
		WidgetID theSelectedWidget = controlView->GetWidgetID();
		/*
		// Toan added here to set proxy server
		if (theSelectedWidget == kAMPRadioAutoWidgetID && theChange == kTrueStateMessage)
		{
			////cout << "select auto mode" << endl;
			g_ProxyEnable = FALSE;
			InterfacePtr<IWidgetParent> iWidgetParent(this, UseDefaultIID());
			if(!iWidgetParent)
				break;
			InterfacePtr<IPanelControlData>	iPanelControlData( 
															  (IPanelControlData*)iWidgetParent->QueryParentFor(IID_IPANELCONTROLDATA) );
			ASSERT(iPanelControlData);
			if(!iPanelControlData)
			{
				break;
			}
			IControlView* proxyPortView = iPanelControlData->FindWidget(kAMPProxySettingWidgetID);
			if (proxyPortView == nil)
			{
				break;
			}
			proxyPortView->Disable();
		}
		
		if (theSelectedWidget == kAMPRadioManualWidgetID && theChange == kTrueStateMessage)
		{
			////cout << "select manual mode" << endl;
			g_ProxyEnable = TRUE;
			InterfacePtr<IWidgetParent> iWidgetParent(this, UseDefaultIID());
			if(!iWidgetParent)
				break;
			InterfacePtr<IPanelControlData>	iPanelControlData( 
															  (IPanelControlData*)iWidgetParent->QueryParentFor(IID_IPANELCONTROLDATA) );
			ASSERT(iPanelControlData);
			if(!iPanelControlData)
			{
				break;
			}
			IControlView* proxyPortView = iPanelControlData->FindWidget(kAMPProxySettingWidgetID);
			if (proxyPortView == nil)
			{
				break;
			}
			proxyPortView->Enable(TRUE, TRUE);
		}
		 */
		if (theSelectedWidget == kAMPButtonAdvanceWidgetId && theChange == kTrueStateMessage)
		{
			LoadSettingInfo();
			DoOpenDialog(kAMPLuginProxyAction);
		}
		
		//--> 

		if (theSelectedWidget == kBscDlgIconSuiteWidgetID && theChange == kTrueStateMessage)		//<--20120420
		{

		}

		if (theSelectedWidget == kOKButtonWidgetID && theChange == kTrueStateMessage)			//<--20120420
		{
			if(g_Username.length() == 0){
				DoOpenDialog(AMPluginCMSLoginAction);
				break;
			}
			int response = 0;
			// get username and password
			//PMString nUsernameString = this->GetTextControlData(kBscUserNameWidgetID);
			//PMString nPasswordString = this->GetTextControlData(kBscPasswordWidgetID);
			RangeProgressBar * DlgProgress;
			//RangeProgressBar * FillProgress;
			DlgProgress = new RangeProgressBar("Connecting...", 0, 200, kTrue, kFalse, nil, kFalse);
			DlgProgress->SetPosition(5);
			//AMPUtils::RenewWorkspaceDir();
			response = HTTPRequestHelper::loginToCMSServer(DlgProgress, 10, 200);
			
			//response = TRUE;
			if (response == 200) { // successful
				
				g_Password = "";
				g_IsLoggedIn = TRUE;
				//AMPUtils::RenewLogFilePath();
				AMPUtils::RenewWorkspaceDir();
				int returnCode = LoadLogHeaderFile(); // load data from log file to plug-in
				
				string sessionID = LoadSessionInfo(); // load data from session info file
				////cout << "***************** unlock stories: " << g_UnlockStories << endl;
				bool canGetNewSession = TRUE;
				////cout << "sessionID " << sessionID << " - " << n_mSessionID << endl;
				if (sessionID.length() > 0 && (sessionID.compare(n_mSessionID) != 0)) {
					// request new session ID here
					////cout << "you have to request new session id" << endl;
					canGetNewSession = AMPUtils::RenewSessionID(sessionID);
					if (canGetNewSession == FALSE) {
						// login failure
						AMPUtils::ClearAllFile();
						AMPUtils::ClearPackageAndSessionInfo();
						DlgProgress->~RangeProgressBar();
					}					
				}

				if (g_Package_id.length() > 0) {
					//LatestOpen = "Restore origin file";
					// login successed
					int16 result = AMPCAlert::ModalAlert
					(
					 PMString("\n\nRestore latest saved version and continue working?"),	// Alert string
					 PMString("Yes"),					// OK button
					 PMString("No"),					// No second button
					 kNullString,
					 kNeedToWaitForDialog,									// Set kNeedToWaitForDialog to default
					 1									// No icon.
					 );
					
					if (result == 1)
					{
						// open latest idml
						SDKFileOpenChooser fileChooser;
						fileChooser.ShowDialog();
						if (fileChooser.IsChosen()) {
							IDFile chosenFile = fileChooser.GetIDFile();
							SDKLayoutHelper openHelper;
							UIDRef docRef = openHelper.OpenDocument(chosenFile);
							ErrorCode reCode = openHelper.OpenLayoutWindow(docRef);
							if(reCode == kSuccess) {
								g_Package_id = "";
								AMPUtils::GetIDFromTextFrame();
							}
						}
					}else if (result == 2)
					{
						if(AMPUtils::FindFrontDocsName(g_Package_id.c_str()) != TRUE) {
							AMPUtils::ResetLogFile();
							AMPUtils::ClearPackageAndSessionInfo();
						}
						g_Package_id = "";
						AMPUtils::GetIDFromTextFrame();
					}
				}
				////cout << "package_id after log in: " << g_Package_id << endl;
			} else if (response == 401) {
				DlgProgress->~RangeProgressBar();
				// login failure due to wrong username or password
				AMPCAlert::ModalAlert
				(
				 "\n\nLogin Failed. Please enter correct username and password.",//kBscDlgLoginFailStringKey,		// Alert string
				 "OK",							// OK button
				 kNullString, 					// No second button
				 kNullString, 					// No third button
				 kNeedToWaitForDialog,			// Set OK button to default
				 1								// No icon.
				 );
				g_Password = "";	
				g_IsLoggedIn = FALSE;
				DoOpenDialog(AMPluginCMSLoginAction);
				
			} else if (response == 407) {
				DlgProgress->~RangeProgressBar();
				// login failure due to wrong username or password
				AMPCAlert::ModalAlert
				(
				 "Proxy authentication required.\n\nPlease check enter correct user and password, and retry.",//kBscDlgLoginFailStringKey,		// Alert string
				 "OK",							// OK button
				 kNullString, 					// No second button
				 kNullString, 					// No third button
				 kNeedToWaitForDialog,			// Set OK button to default
				 1								// No icon.
				 );
				g_Password = "";	
				g_IsLoggedIn = FALSE;
				DoOpenDialog(AMPluginCMSLoginAction);
				
			} else if (response == 305) {
				DlgProgress->~RangeProgressBar();
				// login failure due to wrong username or password
				AMPCAlert::ModalAlert
				(
				 "\n\nPlease configure the Proxy settings for your connection.",//kBscDlgLoginFailStringKey,		// Alert string
				 "OK",							// OK button
				 kNullString, 					// No second button
				 kNullString, 					// No third button
				 kNeedToWaitForDialog,			// Set OK button to default
				 1								// No icon.
				 );
				g_Password = "";	
				g_IsLoggedIn = FALSE;
				DoOpenDialog(AMPluginCMSLoginAction);
			}
			else {
				DlgProgress->~RangeProgressBar();
				// login failure due to something else
				AMPCAlert::ModalAlert
				(
				 "\nCheck internet connection or Proxy settings and try to connect again.",		// Alert string
				 "OK",							// OK button
				 kNullString, 					// No second button
				 kNullString, 					// No third button
				 kNeedToWaitForDialog,			// Set OK button to default
				 1								// No icon.
				 );
				g_Password = "";	
				g_IsLoggedIn = FALSE;
				DoOpenDialog(AMPluginCMSLoginAction);
			}
			
			
			//break;
			string frontDocName = AMPUtils::FrontDocName();
			//if(g_IsLoggedIn == TRUE && g_DocName.length() > 0)	
			//if(g_IsLoggedIn == TRUE  && g_IsCheckOut == TRUE && frontDocName.length() > 0)	
			//if(g_IsLoggedIn == TRUE  && g_DocName.length() > 0 && frontDocName.length() > 0)	
			if(g_IsLoggedIn == TRUE  && g_DocName.length() > 0 && (g_DocName.compare(AMPUtils::FrontDocName()) == 0))
			{
				//bool bSetName = AMPUtils::SetNameDocument();
				//if(bSetName == TRUE)
					//AMPUtils::RefreshMainPanel(kAMPLuginCheckoutActionID);
				AMPUtils::RefreshMainPanel(kAMPLuginCheckoutActionID);
			}else
			{
				AMPUtils::RefreshMainPanel(FALSE);
			}
			
			SaveLogHeaderFile();
			SaveSettingInfo();
			DlgProgress->~RangeProgressBar();
		}
	} while (false);
}

/********************************************************************************************************************
 *****Function: DoCloseDialog
 *****Creator:  Toan Nguyen
 *****IN: int32 nTypeDialog
 *****out: 
 *****Objective: close dialog
 ********************************************************************************************************************/
void DlgCMSLoginDialogObserver::DoCloseDialog(int32 nTypeDialog)
{
	do
	{
		// Get the application interface and the DialogMgr.
		/*
		InterfacePtr<IApplication> application(GetExecutionContextSession()->QueryApplication());
		if (application == nil)
		{
			ASSERT_FAIL("DlgCMSLoginDialogObserver::DoDialog: application invalid");
			break;
		}
		InterfacePtr<IDialogMgr> dialogMgr(application, UseDefaultIID());
		if (dialogMgr == nil)
		{
			ASSERT_FAIL("DlgCMSLoginDialogObserver::DoDialog: dialogMgr invalid"); 
			break;
		}
		*/
		InterfacePtr<IWidgetParent> iWidgetParent(this, UseDefaultIID());
		if(!iWidgetParent)
			break;
		
		InterfacePtr<IDialog> iDialog((IDialog *) iWidgetParent->QueryParentFor(IID_IDIALOG));
		
		iDialog->Close();
	} while (false);
}

/********************************************************************************************************************
 *****Function: DoOpenDialog
 *****Creator:  Toan Nguyen
 *****IN: int32 nTypeDialog
 *****out: 
 *****Objective: open dialog
 ********************************************************************************************************************/
IDialog* DlgCMSLoginDialogObserver::DoOpenDialog(int32 nTypeDialog)
{

	do
	{
		int32	DialogResourceID;
		if (nTypeDialog == AMPluginCMSLoginAction)
		{
			DialogResourceID = kCMSLoginDialogResourceID;
		} 
		else if (nTypeDialog == AMPluginBrowserIssueAction)
		{
			DialogResourceID = kBscSlDlgIssuesDialogResourceID;
		}
		else if (nTypeDialog == kAMPLuginProgressAction)
		{
			DialogResourceID = kAMPProgressDlgResourceID;
		}
		else if (nTypeDialog == kAMPLuginProxyAction)
		{
			DialogResourceID = kAMPProxyDlgResourceID;
		}
		// Get the application interface and the DialogMgr.	
		InterfacePtr<IApplication> application(GetExecutionContextSession()->QueryApplication());
		if (application == nil)
		{
			ASSERT_FAIL("BscDlgActionComponent::DoDialog: application invalid");
			break;
		}
		InterfacePtr<IDialogMgr> dialogMgr(application, UseDefaultIID());
		if (dialogMgr == nil)
		{ 
			ASSERT_FAIL("BscDlgActionComponent::DoDialog: dialogMgr invalid"); 
			break;
		}
		
		// Load the plug-in's resource.
		PMLocaleId nLocale = LocaleSetting::GetLocale();
		RsrcSpec dialogSpec
		(
		 nLocale,					// Locale index from PMLocaleIDs.h. 
		 kAMPPluginID,			// Our Plug-in ID from BasicDialogID.h. 
		 kViewRsrcType,				// This is the kViewRsrcType.
		 DialogResourceID,			// Resource ID for our dialog.
		 kTrue						// Initially visible.
		 );
		
		// CreateNewDialog takes the dialogSpec created above, and also
		// the type of dialog being created (kMovableModal).
		IDialog* dialog = dialogMgr->CreateNewDialog(dialogSpec, IDialog::kMovableModal);
		if (dialog == nil)
		{ 
			ASSERT_FAIL("BscDlgActionComponent::DoDialog: can't create dialog"); 
			break;
		}
		
		// Open the dialog.
		dialog->Open(); 
		
		return dialog;
		
	} while (false);

	return NULL;
}
// End, DlgCMSLoginDialogObserver.cpp.




